home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / bin / util / togeomview.c < prev   
C/C++ Source or Header  |  1993-12-07  |  4KB  |  191 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <sys/signal.h>
  6. #include <sys/file.h>
  7. #include <sys/fcntl.h>
  8. #include <sys/errno.h>
  9. #include <sys/socket.h>
  10. #include <sys/un.h>
  11.  
  12. #ifndef O_NONBLOCK
  13. # define O_NONBLOCK O_NDELAY
  14. #endif
  15. #ifndef FNONBLK
  16. # define FNONBLK FNDELAY
  17. #endif
  18.  
  19. extern int errno;
  20.  
  21. char *todir = "/tmp/geomview";
  22. char *toname = "OOGL";
  23. char *prog;
  24.  
  25. char timedout[] = "Couldn't start geomview\n";
  26.  
  27. static void
  28. interrupt(int sig) { 
  29.     write(2, timedout, sizeof(timedout));
  30.     exit(1);
  31. }
  32.  
  33. /*
  34.  * We've determined that no copy of geomview is running, so start one.
  35.  */
  36. start_gv(char **progtorun, char *toname, int asgeom, int usesock)
  37. {
  38.     char *args[1024];
  39.     int i;
  40.     static char Mprefix[] = "/tmp/geomview/";
  41.     static char Mhow[] = "-Mcp";
  42.  
  43.     signal(SIGALRM, interrupt);
  44.     for(i=0; progtorun[i] != NULL; i++)
  45.     args[i] = progtorun[i];
  46.  
  47.     Mhow[2] = asgeom ? 'g' : 'c';
  48.     Mhow[3] = usesock ? 's' : 'p';
  49.     args[i++] = Mhow;
  50.     args[i++] = strncmp(toname, Mprefix, strlen(Mprefix))
  51.             ? toname : toname + strlen(Mprefix);
  52.  
  53.     if(fork() == 0) {
  54.     close(0);
  55.     setpgrp(0,getpid());
  56.     execvp(progtorun[0], args);
  57.     execvp("gv", args);
  58.     perror("Couldn't exec geomview nor gv");
  59.     kill(getppid(), SIGALRM);
  60.     _exit(1);
  61.     }
  62. }
  63.  
  64. /*
  65.  * Pipe fitting for linking Mathematica to geomview.
  66.  * Starts geomview if not already running.
  67.  */
  68. main(int argc, char *argv[])
  69. {
  70.     int usesock;
  71.     int n, fd = -1;
  72.     int asgeom = 0;
  73.     char pipename[BUFSIZ];
  74.     static char *geomview[] = { "geomview", NULL };
  75.     char **progtorun = geomview;
  76.     char *tail;
  77.     struct sockaddr_un un;
  78.     struct stat st;
  79.  
  80.     prog = argv[0];
  81.     tail = strrchr(prog, '/');
  82.     if(tail) tail++; else tail = argv[0];
  83.     if(tail[0] == 'g') { asgeom = 1; }
  84.  
  85. #ifdef NeXT
  86.     usesock = 1;
  87. #else
  88.     usesock = 0;
  89. #endif
  90.  
  91.     while(argc > 1 && argv[1][0] == '-') {
  92.     for(tail = argv[1]; *++tail; ) {
  93.         switch(*tail) {
  94.         case 'M': asgeom = 1; break;
  95.         case 'g': asgeom = 1; break;
  96.         case 'c': asgeom = 0; break;
  97.         case 'p': usesock = 0; break;
  98.         case 's': usesock = 1; break;
  99.         default: usage();
  100.         }
  101.     }
  102.     argc--, argv++;
  103.     }
  104.  
  105.     if(argc > 1) toname = argv[1];
  106.     if(argc > 2) progtorun = &argv[2];
  107.  
  108.     if(toname[0] == '/') {
  109.     tail = strrchr(toname, '/');
  110.     *tail = '\0';
  111.     todir = toname;
  112.     toname = tail + 1;
  113.     }
  114.     if(access(todir, W_OK) < 0) {
  115.     mkdir(todir, 0777);
  116.     chmod(todir, 0777);
  117.     }
  118.     sprintf(pipename, "%s/%s", todir, toname);
  119.  
  120.     if(stat(pipename, &st) > 0 && ((st.st_mode&S_IFMT)==S_IFSOCK) != usesock)
  121.     unlink(pipename);
  122.  
  123.     if(usesock) {
  124.     strncpy(un.sun_path, pipename, sizeof(un.sun_path)-1);
  125.     un.sun_family = AF_UNIX;
  126.     fd = socket(AF_UNIX, SOCK_STREAM, 0);
  127.     if(connect(fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
  128.         if(errno != ECONNREFUSED && errno != ENOENT) {
  129.         fprintf(stderr, "togeomview: Can't connect to ");
  130.         perror(pipename);
  131.         exit(1);
  132.         }
  133.  
  134.         start_gv(progtorun, pipename, asgeom, usesock);
  135.         for(n = 0; connect(fd, (struct sockaddr*)&un, sizeof(un)) < 0; n++) {
  136.         if(n == 15)
  137.             interrupt(0);
  138.         sleep(1);
  139.         }
  140.     }
  141.     } else {
  142.     /* Use named pipe */
  143. #ifdef S_IFIFO
  144.  
  145.     if(access(pipename, 0) < 0) {
  146.         mknod(pipename, S_IFIFO, 0);
  147.         chmod(pipename, 0666);
  148.     }
  149.     fd = open(pipename, O_WRONLY|O_NONBLOCK);
  150.     if(fd >= 0) {
  151.         fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~(FNDELAY|FNONBLK));
  152.     } else if(errno == ENXIO) {
  153.         start_gv(progtorun, pipename, asgeom, usesock);
  154.         alarm(60);
  155.         fd = open(pipename, O_WRONLY);
  156.         alarm(0);
  157.     }
  158. #endif
  159.     }
  160.     if(fd < 0) {
  161.     fprintf(stderr, "Can't open pipe to geomview: ");
  162.     perror(pipename);
  163.     exit(1);
  164.     }
  165.     while((n = read(0, pipename, sizeof(pipename))) > 0) {
  166.     if(write(fd, pipename, n) < n) {
  167.         perror("Error writing to geomview");
  168.         exit(1);
  169.     }
  170.     }
  171.     exit(0);
  172. }
  173.  
  174. usage()
  175. {
  176.     setlinebuf(stderr);
  177.  
  178.     fprintf(stderr, "Usage: %s [-g] [pipename  [ geomview ... args ] ]\n\
  179. Sends lisp-style commands or (with \"-g\") OOGL geometry data to geomview,\n\
  180. starting a copy if none is yet running.  Uses \"pipename\" as the connection\n\
  181. name; a file by that name is created in the directory \"/tmp/geomview\".\n\
  182. Default pipename is \"OOGL\".  If \"geomview ... args\" are present,\n\
  183. invokes that (if need be) rather than geomview itself.\n\
  184. Examples:\n\
  185.     echo '(geometry fred < dodec.off)' | togeomview  sam\n\
  186.     togeomview -g <dodec.off\n\
  187.     cat my_geomview_script | togeomview bob  gv -wpos 300x300@500,500\n",
  188.         prog);
  189.     exit(1);
  190. }
  191.